#include "power_transfer.h"
#include "msg_receive.h"
#include "msg_handler.h"
#include "BF7006AMxx_sysctrl.h"
#include "power_sys_control.h"
#include "SEGGER_RTT.h"
#include "string.h"
#include "system.h"
#include "bsp.h"

power_tx_timing_t tx_timing = {0};
static uint8_t power_tx_phases = SELECTION_PHASES;
int wait_flg = 1;
uint32_t wait_time = 0;


void set_power_tx_phase(uint8_t phases)
{
	power_tx_phases = phases;
}

uint8_t get_power_tx_phases(void)
{
	return power_tx_phases;
}


int8_t select_phases_handler(uint8_t valid,msg_body_t *msg)
{
	int8_t rval = 1;

	memset(&tx_timing,0,sizeof(power_tx_timing_t));
	if(1){
		set_power_tx_phase(ANALOG_PING_PHASES);
		tx_timing.t_select_start = get_system_tick();
	}
	green_led_on();
	return rval;
}

int8_t analog_ping_phases_handler(uint8_t valid,msg_body_t *msg)
{
	int8_t rval = 1;

	set_power_tx_phase(DIGITAL_PING_PHASES);
	tx_timing.t_analog_ping_start = get_system_tick();
	
	return rval;
}

int8_t digital_ping_phases_handler(uint8_t valid,msg_body_t *msg)
{
	int8_t rval = 1;
	if(!tx_timing.t_digital_ping_start){
		start_power_signal();			//apply a power signal
		tx_timing.t_digital_ping_start = get_system_tick();
	}else{
		if(valid && msg->header == SIGNAL_STRENGTH_PACKET){
			set_power_tx_phase(IDENTIFICATION_CONFIG_PHASES);
			tx_timing.t_identify = get_system_tick();
			return rval;			
		}
		
		if(get_system_tick() - tx_timing.t_digital_ping_start > MAX_T_ping + MAX_T_first){   //ping over time
			end_power_signal();
			set_power_tx_phase(SELECTION_PHASES);
			ask_timer_mod_count_updata();
		//	SEGGER_RTT_printf(0,"[%d] ping time out,switch back to select ping phases \r\n",get_system_tick());
		}
	}	
	return rval;
}

int8_t indentification_config_phases_handler(uint8_t valid,msg_body_t *msg)
{
	int8_t rval = 1;

	if((!tx_timing.t_config) && (get_system_tick()-tx_timing.t_identify > MAX_T_next+MAX_T_max)){//25+170
		end_power_signal();
		set_power_tx_phase(SELECTION_PHASES);
		ask_timer_mod_count_updata();
		SEGGER_RTT_printf(0,"[%d] indentification time out,switch back to select ping phases \r\n\r\n\r\n",get_system_tick());	
	}
	
	if(tx_timing.t_config && get_system_tick() - tx_timing.t_config > (MAX_T_next+MAX_T_max)){
		end_power_signal();
		set_power_tx_phase(SELECTION_PHASES);
		ask_timer_mod_count_updata();
		SEGGER_RTT_printf(0,"[%d] configuration time out,switch back to select ping phases \r\n",get_system_tick());		
	}
	
	if(valid && msg->header == INDENTIFICATION_PACKET){
		tx_timing.t_config  = get_system_tick();
	}
	if((valid && msg->header == CONFIGURATION_PACKET)&& tx_timing.t_config){
		set_power_tx_phase(POWER_TRANSFER_PHASES);	
	
		tx_timing.t_contrl_err = get_system_tick();
		tx_timing.t_recv_power = get_system_tick();	
	}

	return rval;
}

int8_t power_transfer_phases_handler(uint8_t valid,msg_body_t *msg)
{
	int8_t rval = 1;
	static uint8_t led_flg = 0;

	if(valid && msg->header == CONTROL_ERROR_PACKET){
		tx_timing.t_contrl_err = get_system_tick();
	}
	
	if(valid && (msg->header == BIT_8_RECEIVED_POWER_PACKET||msg->header == BIT_24_RECEIVED_POWER_PACKET)){
		tx_timing.t_recv_power = get_system_tick();
	}
	
	
	if(get_system_tick()-tx_timing.t_contrl_err > MAX_T_timeout){//1800
		end_power_signal();
		set_power_tx_phase(SELECTION_PHASES);
		SEGGER_RTT_printf(0,"[%d] control errror packet time out,switch back to select ping phases \r\n",get_system_tick());
		rval = 0;
	}
	if(get_system_tick()-tx_timing.t_recv_power > MAX_T_power){
		end_power_signal();
		set_power_tx_phase(SELECTION_PHASES);		
		SEGGER_RTT_printf(0,"[%d] receive power  packet time out,switch back to select ping phases \r\n",get_system_tick());
		rval = 0;
	}
	
	
	if(get_system_tick() - tx_timing.t_charge_led > LED_T_flicker){
		led_flg = 1-led_flg;
		tx_timing.t_charge_led = get_system_tick();
		
		if(led_flg){
			green_led_on();
		}else{
			green_led_off();
		}
	}
	return rval;
}





void power_tx_handler(void)
{
	uint8_t msg_valid = 0;
	int8_t rval = 1;
	msg_body_t msg = {0};
	
	msg_valid = read_msg_from_fifo(&msg);  

	switch(get_power_tx_phases()){
		case SELECTION_PHASES:
			end_power_signal();
			if(wait_flg){
			wait_time = get_system_tick();
				wait_flg = 0;
			}
			if(get_system_tick()- wait_time > 5*1000){
				rval = select_phases_handler(msg_valid,&msg);
			}
			break;
		case ANALOG_PING_PHASES:
			wait_flg = 1;
			rval = analog_ping_phases_handler(msg_valid,&msg);
			break;
		case DIGITAL_PING_PHASES:
			rval = digital_ping_phases_handler(msg_valid,&msg);
			break;
		case IDENTIFICATION_CONFIG_PHASES:
			rval = indentification_config_phases_handler(msg_valid,&msg);
			break;
		case NEGOTIATION_PHASES:
			
			break;
		case CALIBRATION_PHASES:
			
			break;
		case RENEGOTIATION_PHASE:
			
			break;
		case POWER_TRANSFER_PHASES:
			rval = power_transfer_phases_handler(msg_valid,&msg);			
			break;
		default:
			break;
	}
	
	if(msg_valid && rval){
		ask_msg_handle(&msg);
	}
	
}
